﻿#define  _CRT_SECURE_NO_WARNINGS   1
#include <iostream>
using namespace std;
#pragma once
#include <iostream>
#include <assert.h>
using namespace std;

class Date
{
	//变成Date的友元
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& out,  Date& d);
	friend class A;
public:
	//构造函数
	Date(int year = 2025, int month = 7, int day = 13)
	{
		_year = year;
		_month = month;
		_day = day;
		_cout++;
	}

	//语法理解上初始化列表可以认为是每个成员变量定义初始化的地⽅
	//当构造函数和初始化列表都存在的时候，优先初始化列表。
	//Date(int year,int month, int day)
	//	:_year(20)
	//	,_month(1)
	//	,_day(21)
	//{ }

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//拷贝构造函数
	//不写的话，编译器也会默认生成，根据是否满足自己的需求，来自行手写补充
	//当涉及到深拷贝的时候，就要自己来写拷贝构造函数了
	//涉及到拷贝构造的场景：传参，返回值，类型转化
	Date(const Date& d)	//必须使用引用作为参数，否则就会无线死递归
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	//=运算符重载
	//规定必须重载为成员函数
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}

	//const成员函数，const放在函数后面，用来修饰*this的
	void Printf() const
	{
		cout << _year << '-' << _month << '-' << _day << endl;
		//cout << _cout << endl;
	}
private:

	int _year  ;
	int _month  ;
	int _day ;
	//成员变量可以给缺省值
	//int _year=2025;
	//int _month=7;
	//int _day=14;
	// 
	// 
	//static修饰成员变量
	//类内进行声明
	//类外进行定义初始化
	static int _cout;
};

 int Date::_cout=0;
//ostream和instream的拷贝构造被限制了，所以只能用引用
//<<运算符重载
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << '-' <<d. _month << '-' << d._day << endl;
	return out;
}

//>>运算符重载
istream & operator>>(istream& input,  Date& d)
{
	input >> d._year >> d._month>>d._day ;
	return  input;
}

class A
{
public:
	void fun1(const Date& d)
	{
		d.Printf();
	}
};
//静态成员函数中可以访问其他的静态成员，但是不能访问⾮静态的，因为没有this指针
//可以类名::来访问静态成员变量或静态成员函数，对象也可以访问

//友元---友元函数||友元类
int main()
{
	/*Date d1(2025, 7, 14);
	Date d2(2049, 10,1);
	Date d3(2049, 10,20);*/
	//cin >> d1;
	//d1 = d2=d3;
	//cout << d1<<d2;
	Date d1;
	Date d2;
	Date d3;
	Date d4;
	 //d1.Printf();
	A a1;
	a1.fun1(d1);
	return 0;
}